import json

from django.http import JsonResponse, HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response

from ai.models import HistoryTalkModel, HetongModel
from login.models import UserModel, UserDetailModel
from login.views import UserDetailAPIView
from mytools import my_solution
from mytools.image_ai import image_ai
import logging
from mytools.baiduapi import baiduapi
from login import models
from orders.models import Order
from orders.seralizers import OrderSerializer
from utils.myredis import r
import tempfile
import requests

from utils.Qwen import tell_weather
from utils.yuyin import yuyinai

logger = logging.getLogger(__name__)

from mytools.vector_store_tools import VectorStoreTools
import os
from rest_framework import status
from mytools.my_agent import agent_executor

from mytools.my_factory import InsuranceFactory

#工厂模式ai测试接口
class InsuranceConsultationAPI(APIView):
    """
    保险咨询统一接口
    功能：根据保险类型提供专业咨询，支持医疗保险、意外保险、财产保险等
    """
    VALID_INSURANCE_TYPES = ['medical', 'accident', 'property']
    def post(self, request):
        """
        处理保险咨询请求
        参数:
            - insurance_type: 保险类型(medical/accident/property)
            - question: 咨询问题文本
        返回:
            - 专业回答(包含条款引用和建议)
        """
        # 1. 参数校验
        insurance_type = request.data.get('insurance_type')
        question = request.data.get('question')

        if not all([insurance_type, question]):
            return Response(
                {'error': '缺少必要参数: insurance_type 或 question'},
                status=status.HTTP_400_BAD_REQUEST
            )

        if insurance_type not in self.VALID_INSURANCE_TYPES:
            return Response(
                {'error': f'无效保险类型，可选: {", ".join(self.VALID_INSURANCE_TYPES)}'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 2. 获取专业回答
        try:
            advisor = InsuranceFactory.create_insurance(insurance_type)
            response = advisor.generate_response(question)

            return Response(
                {
                    'insurance_type': insurance_type,
                    'question': question,
                    'answer': response,
                    'sources': self._extract_sources(response)  # 提取引用来源
                },
                status=status.HTTP_200_OK
            )

        except Exception as e:
            return Response(
                {'error': f'咨询处理失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def _extract_sources(self, response: str) -> list:
        """从回答中提取引用的条款(示例实现)"""
        import re
        return re.findall(r'【条款[0-9]+】', response)



#自动审核模块
class InsuranceProcessView(APIView):
    """
    智能保险全流程处理接口
    功能：集成资料审核、条款检索、合同生成、订单状态更新的全自动化处理
    """
    def post(self, request):
            # 1. 接收并验证基础参数
            required_fields = ['aname', 'bname', 'acard_id', 'bcard_id', 'phone', 'relationship', 'order_id']
            if not all(request.data.get(field) for field in required_fields):
                return Response(
                    {'error': f'缺少必填字段: {", ".join(required_fields)}'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            print("oredr"+request.data['order_id'])
            # 2. 构造代理输入（兼容两种输入格式）
            input_data = {
                "aname": request.data['aname'],
                "bname": request.data['bname'],
                "acard_id": request.data['acard_id'],
                "bcard_id": request.data['bcard_id'],
                "phone": request.data['phone'],
                "relationship": request.data['relationship'],
                "effective_date": request.data.get('effective_date'),
                "term_years": request.data.get('term_years', 1),
                "order_id": request.data['order_id']
            }
            # 3. 启动异步任务（唯一新增的核心代码）
            from base.tasks import process_insurance_application
            task = process_insurance_application.delay(input_data)


            # 4. 返回异步响应（简单化处理）
            return Response({
                "status": "processing",
                "message": "保险处理已开始",
                "task_id": task.id,
                "status_url": f"/ai/insurance/status/{task.id}/"
            }, status=status.HTTP_202_ACCEPTED)




# views.py 新增（放在InsuranceProcessView后面）任务状态查询
class InsuranceTaskStatusView(APIView):
    """任务状态查询（保持简单）"""
    def get(self, request, task_id):
        from celery.result import AsyncResult
        task = AsyncResult(task_id)

        if not task.ready():
            return Response({"status": "processing"})

        # 直接返回任务结果（结构与你原来的响应一致）
        return Response(task.result)

class addStatusView(APIView):
    """任务状态查询（保持简单）"""
    def get(self, request):
        user=request.query_params.get('userid')
        review_result=request.query_params.get('text')
        contract_id=request.query_params.get('contract_id')
        print(user,review_result)
        HetongModel.objects.create(review_result=review_result,user_id=int(user),contract_id=contract_id)
        return Response('ok')


class VecotrView(APIView):
    def post(self, request):
        # 定义文件路径
        path=os.path.join("../mypro", 'my_file', 'train.json')#这里可以修改
        # 调用VectorStoreTools类，传入文件路径，并调用set_voctorstore方法
        data=VectorStoreTools(path).set_voctorstore('docx')
        # 如果data不为空，则返回成功信息
        if data:
            return Response({'code': 200, 'msg': '向量库更新成功'})
        # 否则返回失败信息
        else:
            return Response({'code': 400, 'msg': '向量库更新失败'})



#识别图片，辨认其所属的log ,在项目中没有什么用单纯是我练手用的不用管
class Images(APIView):
    '''识别图片，辨认其所属的log ,在项目中没有什么用单纯是我练手用的不用管'''
    def post(self, request):
        try:
            # 获取图片URL或文件
            image_url = request.data.get('image_url', '').strip()  # 去除可能的空白字符
            image_file = request.FILES.get('image_file')

            if image_url:
                # 使用URL识别
                res = image_ai.recognize_logo(image_url=image_url)
            elif image_file:
                # 保存临时文件后识别
                import tempfile
                with tempfile.NamedTemporaryFile(delete=True) as tmp:
                    for chunk in image_file.chunks():
                        tmp.write(chunk)
                    tmp.flush()
                    res = image_ai.recognize_logo(image_path=tmp.name)
            else:
                return Response({'error': '必须提供image_url或image_file参数'}, status=400)

            return Response({'result': res})

        except Exception as e:
            return Response({'error': str(e)}, status=500)

class BaiDuApiCard(APIView):
    def post(self,request):

        url=request.data.get('url')
        r.list_push('baidulist', url)
        res=baiduapi.idcard(url)
        return Response({"data": res,"code":10000})


#人脸识别
from rest_framework.response import Response
from rest_framework import status


class Renlian(APIView):
    def post(self, request):
        # 1. 参数验证
        image_a = request.data.get('image_a')  # 身份证照片
        image_b = request.data.get('image_b')  # 实时拍摄照片

        if not image_a or not image_b:
            return Response(
                {"error": "需要提供身份证照片和实时拍摄照片", "code": 4000},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            # 2. 人脸比对
            face_res = baiduapi.face_detect(image_a, image_b)
            if not face_res['success']:
                return Response(
                    {
                        "error": face_res['error_msg'],
                        "code": 4000,
                        "detail": face_res.get('raw_data', {})
                    },
                    status=status.HTTP_200_OK
                )

            # 3. 身份证信息识别
            id_card_info = baiduapi.idcard(image_a)
            if not id_card_info or not id_card_info.get('id_number'):
                return Response(
                    {
                        "error": "身份证信息识别失败",
                        "code": 4000,
                        "detail": {
                            "hint": "请确保证件清晰无遮挡",
                            "id_card_info": id_card_info
                        }
                    },
                    status=status.HTTP_200_OK
                )

            # 4. 返回成功结果
            return Response(
                {
                    "data": {
                        "score": face_res['score'],
                        "match": True,
                        "id_card_info": {
                            "name": id_card_info['name'],
                            "id_number": id_card_info['id_number'][:3] + "****" + id_card_info['id_number'][-4:],  # 脱敏处理
                            "gender": id_card_info['gender']
                        },
                        "liveness_score": face_res.get('raw_data', {}).get('result', {}).get('liveness', {}).get('livemapscore')
                    },
                    "code": 10000
                },
                status=status.HTTP_200_OK
            )

        except Exception as e:
            return Response(
                {
                    "error": "系统处理异常",
                    "code": 5000,
                    "detail": str(e)
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
import base64
# class IdCard(APIView):
#     def __init__(self, **kwargs):
#         super().__init__(**kwargs)
#     def post(self, request):
#         try:
#             image_url = request.data.get('image_url', '').strip()
#             image_file = request.FILES.get('image_file')
#             id_card_side = request.data.get('id_card_side', 'front').lower()
#             if id_card_side not in ['front', 'back']:
#                 return Response({'error': 'id_card_side参数必须是front或back'}, status=400)
#             if image_url:
#                 try:
#                     response = requests.get(image_url)
#                     response.raise_for_status()
#                     # 直接在内存中处理，不写入临时文件
#                     image_data = base64.b64encode(response.content).decode('utf-8')
#                     res = self._recognize_from_data(image_data, id_card_side)
#                 except Exception as e:
#                     logger.error(f"下载网络图片失败: {str(e)}")
#                     return Response({'error': f'下载图片失败: {str(e)}'}, status=400)
#             elif image_file:
#                 # 直接在内存中处理上传的文件
#                 image_data = base64.b64encode(image_file.read()).decode('utf-8')
#                 res = self._recognize_from_data(image_data, id_card_side)
#             else:
#                 return Response({'error': '必须提供image_url或image_file参数'}, status=400)
#             if 'error' in res:
#                 logger.error(f"身份证识别失败: {res['error']}")
#                 return Response({'error': res['error']}, status=500)
#             standardized_result = self._standardize_result(res, id_card_side)
#             return Response({'result': standardized_result})
#         except Exception as e:
#             logger.error(f"身份证识别处理异常: {str(e)}", exc_info=True)
#             return Response({'error': f'服务器处理异常: {str(e)}'}, status=500)
#     def _recognize_from_data(self, image_data, id_card_side):
#         """直接从base64编码的图像数据识别"""
#         if not self.id_card_recognizer.access_token:
#             self.id_card_recognizer.get_access_token()
#             if not self.id_card_recognizer.access_token:
#                 return {"error": "无法获取access_token"}
#         url = f"https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token={self.id_card_recognizer.access_token}"
#         payload = {
#             'image': image_data,
#             'id_card_side': id_card_side,
#             'detect_risk': 'false',
#             'detect_quality': 'false'
#         }
#         headers = {
#             'Content-Type': 'application/x-www-form-urlencoded',
#             'Accept': 'application/json'
#         }
#         try:
#             response = requests.post(url, headers=headers, data=payload)
#             if response.status_code == 200:
#                 return response.json()
#             else:
#                 return {"error": f"识别失败，状态码：{response.status_code}", "response": response.text}
#         except Exception as e:
#             return {"error": f"请求识别接口时发生异常：{str(e)}"}
#     def _standardize_result(self, raw_result, id_card_side):
#         """
#         标准化识别结果
#         :param raw_result: 原始识别结果
#         :param id_card_side: 身份证面(front/back)
#         :return: 标准化后的结果字典
#         """
#         if id_card_side == 'front':
#             return {
#                 'name': raw_result.get('words_result', {}).get('姓名', {}).get('words', ''),
#                 'gender': raw_result.get('words_result', {}).get('性别', {}).get('words', ''),
#                 'ethnicity': raw_result.get('words_result', {}).get('民族', {}).get('words', ''),
#                 'birth_date': raw_result.get('words_result', {}).get('出生', {}).get('words', ''),
#                 'address': raw_result.get('words_result', {}).get('住址', {}).get('words', ''),
#                 'id_number': raw_result.get('words_result', {}).get('公民身份号码', {}).get('words', ''),
#                 'risk_type': raw_result.get('risk_type', ''),
#                 'image_status': raw_result.get('image_status', '')
#             }
#         else:
#             return {
#                 'issue_authority': raw_result.get('words_result', {}).get('签发机关', {}).get('words', ''),
#                 'valid_period': raw_result.get('words_result', {}).get('失效日期', {}).get('words', ''),
#                 'risk_type': raw_result.get('risk_type', ''),
#                 'image_status': raw_result.get('image_status', '')
#             }

from mytools.gaode_map import map


class Gaode_Map(APIView):
    # 定义一个post方法，用于接收请求
    def post(self,request):
        # 获取请求中的城市和类型
        city=request.data.get('city')
        types=request.data.get('types')
        # 如果类型为中国人寿
        if types=='中国人寿':
            # 设置poi_num为160402
            poi_num=160402
            # 调用map.get_poi2方法，获取响应
            response=map.get_poi2(keywords=city,types=poi_num)
            # 打印响应
            print(response)
            # 返回响应
            return Response({'status': 'success', 'message': 'yes', 'data': response})
        # 如果类型为新华人寿
        elif types=='新华人寿':
            # 设置poi_num为160406
            poi_num=160406
            # 调用map.get_poi2方法，获取响应
            response=map.get_poi2(keywords=city,types=poi_num)
            # 返回响应
            return response
        # 如果类型不是中国人寿或新华人寿
        else:
            # 返回错误信息
            return Response('请重新定位')

class Map_Show(APIView):
    def post(self,request):
        #读取用户的地址
        user_id=request.data.get('userid')
        print(user_id)
        user_data=models.UserModel.objects.filter(id=user_id).first()

        print(user_data)
        print('-------------------------------')
        user_address=user_data.detail.address
        print('用户的地址',user_address)
        #调用高德地图api获取经纬度
        try:
            #获取经纬度
            location = map.address_code(user_address)
            if location:
                img=map.state_map(location=location)
                return Response({'status': 'success', 'message': 'yes', 'data': img,'address':user_address})
            else:
                return Response({'status': 'success', 'message': 'no'})
        except Exception as e:
            return Response({'status': 'success', 'message': 'no', 'data': e})






from mytools.my_factory import InsuranceFactory
#ai智能对话助手这里考虑采用工厂模式，提供不同专业方向的ai小助手
class Session_ai(APIView):
    def post(self,request):
        try:
            type=request.data.get('type')
            user_input=request.data.get('user_input')
            if type=='医疗保险':
                insurance=InsuranceFactory.create_insurance("medical")
                response = insurance.generate_response(user_input)
                print(response)
                return Response(response)
            elif type=='事故保险':
                insurance=InsuranceFactory.create_insurance("accident")
                response=insurance.generate_response(user_input)
                print(response)
                return Response(response)
            elif type=='财产保险':
                insurance = InsuranceFactory.create_insurance("property")
                response = insurance.generate_response(user_input)
                print(response)
                return Response(response)
            else:
                return Response({'error': '必须提供type参数'}, status=400)
        except Exception as e:

            return Response({'error': str(e)}, status=500)


#历史对话保存
class Save_history(APIView):
    def post(self,request):
        user_id=request.data.get('user_id')
        type=request.data.get('type')
        history=request.data.get('history')
        data = HistoryTalkModel.objects.filter(user_id=user_id, type_id=type, content=history).first()
        if data:
            HistoryTalkModel.objects.filter(user_id=user_id, type_id=type).update(content=history)
            return Response({'code': 200, 'message': '已存在'})
        else:
            HistoryTalkModel.objects.create(user_id=user_id, type_id=type, content=history)
            return Response({'code': 200, 'message': '添加成功'})



from django.http import JsonResponse
from django.views import View
from mytools.agentWeather import query_weather
import time


class WeatherView(View):
    def get(self, request):
        userid=request.GET.get('user_id')
        city = UserModel.objects.get(id=userid)
        if city.detail.address is None:
            return JsonResponse({
                'weather': "您好，欢迎回来",
                'tell': "城市未定，心已启程",
            })
        start_time = time.time()
        response=r.get_weather(userid)
        if response:
            my_dict = json.loads(response)
            return JsonResponse({
                'success': True,
                'city': city.detail.address,
                'weather': my_dict['weather'],
                'tell': my_dict['tell'],
                'time_used': round(time.time() - start_time, 2)
            })
        try:
            weather_result = query_weather(city.detail.address)
            tell = tell_weather(weather_result)
            dic= {"weather":weather_result,"tell":tell}
            r.set_weather(userid,60*60*24,json.dumps(dic))
            return JsonResponse({
                'success': True,
                'city': city.detail.address,
                'weather': weather_result,
                'tell':tell,
                'time_used': round(time.time() - start_time, 2)
            })
        except Exception as e:
            return JsonResponse({
                'success': False,
                'error': str(e),
                'time_used': round(time.time() - start_time, 2)
            }, status=500)


class InsuranceAgentView(APIView):
    def post(self, request):
        """
        保险核保助手API接口
        接收JSON格式请求：{"user_input": "用户输入内容", "chat_history": [历史对话数组]}
        返回JSON格式响应：{"response": "AI回复内容", "chat_history": [更新后的历史对话]}
        """
        try:
            # 获取请求数据
            data = request.data
            user_input = data.get('user_input', '')
            chat_history = data.get('chat_history', [])

            # 调用Agent处理请求
            response = my_solution.agent_executor.invoke({
                "input": user_input,
                "chat_history": chat_history
            })

            # 返回响应
            return Response({
                'response': response['output'],
                'chat_history': response.get('chat_history', [])
            })

        except Exception as e:
            return Response({
                'error': f'处理请求时出错: {str(e)}',
                'details': '请确保请求格式正确: {"user_input": "消息内容", "chat_history": []}'
            }, status=500)

class ListionView(APIView):
    def post(self, request):
        shopid=request.data.get('shopid')
        input = HetongModel.objects.filter(contract_id=shopid).first()
        yuyin = yuyinai
        # audio_data = yuyin.get_listion('你反手无力，正手不精，脚步松散，反应迟钝，没一个动作像样！就你还想和我同台较量吗？做你的美梦！')
        audio_data = yuyin.get_listion(input.review_result)
        # 返回二进制响应，设置正确的 Content-Type
        return HttpResponse(audio_data, content_type='audio/mp3')  # 根据实际音频格式调整
class HetongView(APIView):
    def get(self, request):
        shopid=request.query_params.get('shopid')
        input = HetongModel.objects.filter(contract_id=shopid).first()
        return Response({'data':input.review_result})

class GetShopIDView(APIView):
    def get(self, request):
        userid=request.query_params.get('user_id')
        ShopID=Order.objects.filter(order_user_id=userid)
        serial=OrderSerializer(ShopID,many=True)
        return Response({'data': serial.data})

